/*******************************************************************************
* Project: QSAR(Cute Software Architecture) 
*
* Copyright: Copyright(C) 2024 by YuetingBen, All Rights Reserved
*
* File name: DcmDspSvc19.c
*
* Brief: ;
*
* Author: Yueting.Ben
*
* Module: Dcm
*
*******************************************************************************/

/** HEADER FILES **/
#include "DcmDspSvc19.h"


/** MACRO DEFINITION **/

/* The following index refer to Dcm_MsgContextType reqData and resData, start after service identifier(which is not part
of this data) */

/* reportNumberOfDTCByStatusMask, reportNumberOfDTCBySeverityMaskRecord, reportNumberOfMirrorMemoryDTCByStatusMask,
reportNumberOfEmissionsRelatedOBDDTCByStatusMask */
#define DCM_REQ_DTC_REPORT_NUMBER_DTC_STATUS_MASK_INDEX  1u

#define DCM_RES_DTC_REPORT_NUMBER_DTC_FORMAT_INDEX      2u
#define DCM_RES_DTC_REPORT_NUMBER_DTC_COUNT_HIGH_INDEX      3u
#define DCM_RES_DTC_REPORT_NUMBER_DTC_COUNT_LOW_INDEX      4u

/* reportDTCByStatusMask, reportSupportedDTCs, reportFirstTestFailedDTC, reportFirstConfirmedDTC,
reportMostRecentTestFailedDTC, reportMostRecentConfirmedDTC, reportMirrorMemoryDTCByStatusMask, reportEmissionsRela */
#define DCM_REQ_DTC_AND_STATUS_DTC_STATUS_MASK_INDEX  1u

#define DCM_RES_DTC_STATUS_AVAILABILITY_MASK_INDEX      1u
#define DCM_RES_DTC_AND_STATUS_RECORD_START_INDEX 2u
#define DCM_RES_DTC_AND_STATUS_RECORD_HIGH_INDEX 0u
#define DCM_RES_DTC_AND_STATUS_RECORD_MIDDLE_INDEX 1u
#define DCM_RES_DTC_AND_STATUS_RECORD_LOW_INDEX 2u
#define DCM_RES_DTC_AND_STATUS_RECORD_STATUS_INDEX 3u
#define DCM_RES_DTC_AND_STATUS_RECORD_ELEMENT_LENGTH 4u

/* reportDTCSnapshotIdentification, reportDTCSnapshotRecordByDTCNumber */
#define DCM_REQ_SNAPSHOT_DTC_MASK_RECORD_HIGH_INDEX  1u
#define DCM_REQ_SNAPSHOT_DTC_MASK_RECORD_MIDDLE_INDEX  2u
#define DCM_REQ_SNAPSHOT_DTC_MASK_RECORD_LOW_INDEX  3u
#define DCM_REQ_SNAPSHOT_DTC_RECORD_NUMBER_INDEX  4u

#define DCM_RES_SNAPSHOT_DTC_AND_STATUS_RECORD_HIGH_INDEX        1u
#define DCM_RES_SNAPSHOT_DTC_AND_STATUS_RECORD_MIDDLE_INDEX      2u
#define DCM_RES_SNAPSHOT_DTC_AND_STATUS_RECORD_LOW_INDEX         3u
#define DCM_RES_SNAPSHOT_DTC_AND_STATUS_RECORD_STATUS_INDEX      4u
#define DCM_RES_SNAPSHOT_DTC_DATA_RECORD_START_INDEX             5u

/* reportDTCExtendedDataRecordByDTCNumber, reportMirrorMemoryDTCExtendedDataRecordByDTCNumber */
#define DCM_REQ_EXTEND_DATA_DTC_MASK_RECORD_HIGH_INDEX  1u
#define DCM_REQ_EXTEND_DATA_DTC_MASK_RECORD_MIDDLE_INDEX  2u
#define DCM_REQ_EXTEND_DATA_DTC_MASK_RECORD_LOW_INDEX  3u
#define DCM_REQ_EXTEND_DATA_DTC_RECORD_NUMBER_INDEX  4u

#define DCM_RES_EXTEND_DATA_DTC_AND_STATUS_RECORD_HIGH_INDEX        1u
#define DCM_RES_EXTEND_DATA_DTC_AND_STATUS_RECORD_MIDDLE_INDEX      2u
#define DCM_RES_EXTEND_DATA_DTC_AND_STATUS_RECORD_LOW_INDEX         3u
#define DCM_RES_EXTEND_DATA_DTC_AND_STATUS_RECORD_STATUS_INDEX      4u
#define DCM_RES_EXTEND_DATA_DTC_DATA_RECORD_START_INDEX             5u


/** TYPEDEF DEFINITION **/


/** LOCAL DATA DECLARATION **/


/** GLOBAL DATA DECLARATION **/


/** LOCAL FUNCTION DECLARATION **/


/** GLOBAL FUNCTION DECLARATION **/
Std_ReturnType DcmDsp_Svc19_01_Processor(
    Dcm_ExtendedOpStatusType OpStatus,
    Dcm_MsgContextType* pMsgContext,
    Dcm_NegativeResponseCodeType* ErrorCode
);

Std_ReturnType DcmDsp_Svc19_02_Processor(
    Dcm_ExtendedOpStatusType OpStatus,
    Dcm_MsgContextType* pMsgContext,
    Dcm_NegativeResponseCodeType* ErrorCode
);

Std_ReturnType DcmDsp_Svc19_04_Processor(
    Dcm_ExtendedOpStatusType OpStatus,
    Dcm_MsgContextType* pMsgContext,
    Dcm_NegativeResponseCodeType* ErrorCode
);

Std_ReturnType DcmDsp_Svc19_06_Processor(
    Dcm_ExtendedOpStatusType OpStatus,
    Dcm_MsgContextType* pMsgContext,
    Dcm_NegativeResponseCodeType* ErrorCode
);

Std_ReturnType DcmDsp_Svc19_0A_Processor(
    Dcm_ExtendedOpStatusType OpStatus,
    Dcm_MsgContextType* pMsgContext,
    Dcm_NegativeResponseCodeType* ErrorCode
);

/** LOCAL DATA **/


/** GLOBAL DATA **/


/** LOCAL FUNCTION **/


/** GLOBAL FUNCTION **/

/*******************************************************************************
* -Name            DcmDsp_Svc19_01_Processor
* -Brief           Processor for ReadDTCInformation (19 hex) sub service 
* -Details         None
* -Param[in]       OpStatus: The operations status        
* -Param[in, out]  pMsgContext: Message context 
* -Param[out]      ErrorCode: Negative response code
* -Return          E_OK:          
*                  E_NOT_OK: 
*******************************************************************************/
Std_ReturnType DcmDsp_Svc19_01_Processor(
    Dcm_ExtendedOpStatusType OpStatus,
    Dcm_MsgContextType* pMsgContext,
    Dcm_NegativeResponseCodeType* ErrorCode
)
{
    Std_ReturnType retVal = E_OK;
    Dem_UdsStatusByteType dtcAvailabilityMask;
    uint16 dtcNumber;
    
    Dem_GetDTCStatusAvailabilityMask(DemConf_DemClientId_01, &dtcAvailabilityMask, DEM_DTC_ORIGIN_PRIMARY_MEMORY);

    Dem_SetDTCFilter(DemConf_DemClientId_01,
                        pMsgContext->reqData[DCM_REQ_DTC_REPORT_NUMBER_DTC_STATUS_MASK_INDEX],
                        EM_DTC_FORMAT_UDS,
                        DEM_DTC_ORIGIN_PRIMARY_MEMORY,
                        RESET,
                        DEM_SEVERITY_NO_SEVERITY, /* DTCSeverityMask */
                        RESET);

    Dem_GetNumberOfFilteredDTC(DemConf_DemClientId_01, &dtcNumber);

    pMsgContext->resData[DCM_RES_DTC_STATUS_AVAILABILITY_MASK_INDEX] = dtcAvailabilityMask;
    pMsgContext->resData[DCM_RES_DTC_REPORT_NUMBER_DTC_FORMAT_INDEX] = dtcAvailabilityMask;
    pMsgContext->resData[DCM_RES_DTC_REPORT_NUMBER_DTC_COUNT_HIGH_INDEX] = (uint8)(dtcNumber >> 8u);
    pMsgContext->resData[DCM_RES_DTC_REPORT_NUMBER_DTC_COUNT_LOW_INDEX] = (uint8)(dtcNumber);
    pMsgContext->resDataLen = 5u;

    return(retVal);
}

/*******************************************************************************
* -Name            DcmDsp_Svc19_02_Processor
* -Brief           Processor for ReadDTCInformation (19 hex) sub service 
* -Details         None
* -Param[in]       OpStatus: The operations status        
* -Param[in, out]  pMsgContext: Message context 
* -Param[out]      ErrorCode: Negative response code
* -Return          E_OK:          
*                  E_NOT_OK: 
*******************************************************************************/
Std_ReturnType DcmDsp_Svc19_02_Processor(
    Dcm_ExtendedOpStatusType OpStatus,
    Dcm_MsgContextType* pMsgContext,
    Dcm_NegativeResponseCodeType* ErrorCode
)
{
    Std_ReturnType retVal = E_OK;
    Dem_UdsStatusByteType dtcAvailabilityMask;
    uint32 dtc;
    Dem_UdsStatusByteType dtcStatus;

    Dem_GetDTCStatusAvailabilityMask(DemConf_DemClientId_01, &dtcAvailabilityMask, DEM_DTC_ORIGIN_PRIMARY_MEMORY);

    Dem_SetDTCFilter(DemConf_DemClientId_01,
                        pMsgContext->reqData[DCM_REQ_DTC_AND_STATUS_DTC_STATUS_MASK_INDEX],
                        EM_DTC_FORMAT_UDS,
                        DEM_DTC_ORIGIN_PRIMARY_MEMORY,
                        RESET,
                        DEM_SEVERITY_NO_SEVERITY, /* DTCSeverityMask */
                        RESET);
                        
    pMsgContext->resData[DCM_RES_DTC_STATUS_AVAILABILITY_MASK_INDEX] = dtcAvailabilityMask;
    pMsgContext->resDataLen = 2u;
    while(E_OK == Dem_GetNextFilteredDTC(DemConf_DemClientId_01, (uint32*)(&dtc), (uint8*)(&dtcStatus)))
    {
        pMsgContext->resData[pMsgContext->resDataLen + DCM_RES_DTC_AND_STATUS_RECORD_HIGH_INDEX] = (uint8)(dtc >> 16u);
        pMsgContext->resData[pMsgContext->resDataLen + DCM_RES_DTC_AND_STATUS_RECORD_MIDDLE_INDEX] = (uint8)(dtc >> 8u);
        pMsgContext->resData[pMsgContext->resDataLen + DCM_RES_DTC_AND_STATUS_RECORD_LOW_INDEX] = (uint8)(dtc);
        pMsgContext->resData[pMsgContext->resDataLen + DCM_RES_DTC_AND_STATUS_RECORD_STATUS_INDEX] = dtcStatus;
        pMsgContext->resDataLen = pMsgContext->resDataLen + DCM_RES_DTC_AND_STATUS_RECORD_ELEMENT_LENGTH;
    }
    
    return(retVal);
}

/*******************************************************************************
* -Name            DcmDsp_Svc19_04_Processor
* -Brief           Processor for ReadDTCInformation (19 hex) sub service 
* -Details         None
* -Param[in]       OpStatus: The operations status        
* -Param[in, out]  pMsgContext: Message context 
* -Param[out]      ErrorCode: Negative response code
* -Return          E_OK:          
*                  E_NOT_OK: 
*******************************************************************************/
Std_ReturnType DcmDsp_Svc19_04_Processor(
    Dcm_ExtendedOpStatusType OpStatus,
    Dcm_MsgContextType* pMsgContext,
    Dcm_NegativeResponseCodeType* ErrorCode
)
{
    Std_ReturnType retVal = E_OK;
    uint16 buffSize;
    uint32 dtc;
    Dem_UdsStatusByteType dtcStatus;

    dtc = ((uint32)(pMsgContext->reqData[DCM_REQ_SNAPSHOT_DTC_MASK_RECORD_HIGH_INDEX] << 16u)
          | (uint32)(pMsgContext->reqData[DCM_REQ_SNAPSHOT_DTC_MASK_RECORD_MIDDLE_INDEX] << 16u)
          | (uint32)(pMsgContext->reqData[DCM_REQ_SNAPSHOT_DTC_MASK_RECORD_LOW_INDEX]));

    Dem_SelectDTC(DemConf_DemClientId_01, dtc, EM_DTC_FORMAT_UDS, DEM_DTC_ORIGIN_PRIMARY_MEMORY);
    Dem_SelectFreezeFrameData(DemConf_DemClientId_01, pMsgContext->reqData[DCM_REQ_SNAPSHOT_DTC_RECORD_NUMBER_INDEX]);
    Dem_GetStatusOfDTC(DemConf_DemClientId_01, (uint8*)(&dtcStatus));

    pMsgContext->resData[DCM_RES_SNAPSHOT_DTC_AND_STATUS_RECORD_HIGH_INDEX] = pMsgContext->reqData[DCM_REQ_SNAPSHOT_DTC_MASK_RECORD_HIGH_INDEX];
    pMsgContext->resData[DCM_RES_SNAPSHOT_DTC_AND_STATUS_RECORD_MIDDLE_INDEX] = pMsgContext->reqData[DCM_REQ_SNAPSHOT_DTC_MASK_RECORD_MIDDLE_INDEX];
    pMsgContext->resData[DCM_RES_SNAPSHOT_DTC_AND_STATUS_RECORD_LOW_INDEX] = pMsgContext->reqData[DCM_REQ_SNAPSHOT_DTC_MASK_RECORD_LOW_INDEX];
    pMsgContext->resData[DCM_RES_SNAPSHOT_DTC_AND_STATUS_RECORD_STATUS_INDEX] = dtcStatus;
    pMsgContext->resDataLen = 5u;
    while(E_OK == Dem_GetNextFreezeFrameData(DemConf_DemClientId_01, (uint8*)(&pMsgContext->resData[pMsgContext->resDataLen]), (uint16*)&buffSize))
    {
        pMsgContext->resDataLen = pMsgContext->resDataLen + buffSize;
    }
    pMsgContext->resDataLen = pMsgContext->resDataLen + buffSize;

    return(retVal);
}

/*******************************************************************************
* -Name            DcmDsp_Svc19_06_Processor
* -Brief           Processor for ReadDTCInformation (19 hex) sub service 
* -Details         None
* -Param[in]       OpStatus: The operations status        
* -Param[in, out]  pMsgContext: Message context 
* -Param[out]      ErrorCode: Negative response code
* -Return          E_OK:          
*                  E_NOT_OK: 
*******************************************************************************/
Std_ReturnType DcmDsp_Svc19_06_Processor(
    Dcm_ExtendedOpStatusType OpStatus,
    Dcm_MsgContextType* pMsgContext,
    Dcm_NegativeResponseCodeType* ErrorCode
)
{
    Std_ReturnType retVal = E_OK;
    uint16 buffSize;
    uint32 dtc;
    Dem_UdsStatusByteType dtcStatus;

    dtc = ((uint32)(pMsgContext->reqData[DCM_REQ_EXTEND_DATA_DTC_MASK_RECORD_HIGH_INDEX] << 16u)
          | (uint32)(pMsgContext->reqData[DCM_REQ_EXTEND_DATA_DTC_MASK_RECORD_MIDDLE_INDEX] << 16u)
          | (uint32)(pMsgContext->reqData[DCM_REQ_EXTEND_DATA_DTC_MASK_RECORD_LOW_INDEX]));

    Dem_SelectDTC(DemConf_DemClientId_01, dtc, EM_DTC_FORMAT_UDS, DEM_DTC_ORIGIN_PRIMARY_MEMORY);
    Dem_SelectExtendedDataRecord(DemConf_DemClientId_01, pMsgContext->reqData[DCM_REQ_EXTEND_DATA_DTC_RECORD_NUMBER_INDEX]);

    Dem_GetStatusOfDTC(DemConf_DemClientId_01, (uint8*)(&dtcStatus));

    pMsgContext->resData[DCM_RES_EXTEND_DATA_DTC_AND_STATUS_RECORD_HIGH_INDEX] = pMsgContext->reqData[DCM_REQ_EXTEND_DATA_DTC_MASK_RECORD_HIGH_INDEX];
    pMsgContext->resData[DCM_RES_EXTEND_DATA_DTC_AND_STATUS_RECORD_MIDDLE_INDEX] = pMsgContext->reqData[DCM_REQ_EXTEND_DATA_DTC_MASK_RECORD_MIDDLE_INDEX];
    pMsgContext->resData[DCM_RES_EXTEND_DATA_DTC_AND_STATUS_RECORD_LOW_INDEX] = pMsgContext->reqData[DCM_REQ_EXTEND_DATA_DTC_MASK_RECORD_LOW_INDEX];
    pMsgContext->resData[DCM_RES_EXTEND_DATA_DTC_AND_STATUS_RECORD_STATUS_INDEX] = dtcStatus;
    pMsgContext->resDataLen = 5u;
    while(E_OK == Dem_GetNextExtendedDataRecord(DemConf_DemClientId_01, (uint8*)(&pMsgContext->resData[pMsgContext->resDataLen]), (uint16*)&buffSize))
    {
        pMsgContext->resDataLen = pMsgContext->resDataLen + buffSize;
    }
    pMsgContext->resDataLen = pMsgContext->resDataLen + buffSize;

    return(retVal);
}

/*******************************************************************************
* -Name            DcmDsp_Svc19_0A_Processor
* -Brief           Processor for ReadDTCInformation (19 hex) sub service 
* -Details         None
* -Param[in]       OpStatus: The operations status        
* -Param[in, out]  pMsgContext: Message context 
* -Param[out]      ErrorCode: Negative response code
* -Return          E_OK:          
*                  E_NOT_OK: 
*******************************************************************************/
Std_ReturnType DcmDsp_Svc19_0A_Processor(
    Dcm_ExtendedOpStatusType OpStatus,
    Dcm_MsgContextType* pMsgContext,
    Dcm_NegativeResponseCodeType* ErrorCode
)
{
    Std_ReturnType retVal = E_OK;
    Dem_UdsStatusByteType dtcAvailabilityMask;
    uint32 dtc;
    Dem_UdsStatusByteType dtcStatus;

    Dem_GetDTCStatusAvailabilityMask(DemConf_DemClientId_01, &dtcAvailabilityMask, DEM_DTC_ORIGIN_PRIMARY_MEMORY);

    Dem_SetDTCFilter(DemConf_DemClientId_01,
                        0x00, /* Retrieving all supported DTC */
                        EM_DTC_FORMAT_UDS,
                        DEM_DTC_ORIGIN_PRIMARY_MEMORY,
                        RESET,
                        DEM_SEVERITY_NO_SEVERITY, /* DTCSeverityMask */
                        RESET);
                        
    pMsgContext->resData[DCM_RES_DTC_STATUS_AVAILABILITY_MASK_INDEX] = dtcAvailabilityMask;
    pMsgContext->resDataLen = 2u;
    while(E_OK == Dem_GetNextFilteredDTC(DemConf_DemClientId_01, (uint32*)(&dtc), (uint8*)(&dtcStatus)))
    {
        pMsgContext->resData[pMsgContext->resDataLen + DCM_RES_DTC_AND_STATUS_RECORD_HIGH_INDEX] = (uint8)(dtc >> 16u);
        pMsgContext->resData[pMsgContext->resDataLen + DCM_RES_DTC_AND_STATUS_RECORD_MIDDLE_INDEX] = (uint8)(dtc >> 8u);
        pMsgContext->resData[pMsgContext->resDataLen + DCM_RES_DTC_AND_STATUS_RECORD_LOW_INDEX] = (uint8)(dtc);
        pMsgContext->resData[pMsgContext->resDataLen + DCM_RES_DTC_AND_STATUS_RECORD_STATUS_INDEX] = dtcStatus;
        pMsgContext->resDataLen = pMsgContext->resDataLen + DCM_RES_DTC_AND_STATUS_RECORD_ELEMENT_LENGTH;
    }
    
    return(retVal);
}

